# -*- coding: UTF-8 -*-
import commands
import hashlib
import json
import os

import flask
from flask import Blueprint
from flask import jsonify
from flask import render_template
from flask import request
from flask import session
from flask_jwt_extended import create_access_token
from flask_jwt_extended import create_refresh_token
from flask_jwt_extended import get_jwt_identity
from flask_jwt_extended import jwt_refresh_token_required
from flask_jwt_extended import jwt_required

import lte_controller
from extention import jwt
from web import Config

web = Blueprint("api", __name__)

users = {'root': {'password': 'f4da50a980fc0d608756c69671d8725d'},
         'admin': {'password': 'f4da50a980fc0d608756c69671d8725d'}}
login_user_file = '/root/modb/login_user.txt'


def get_hex_pwd(current_pw):
    """
    密码加密
    """
    m = hashlib.md5()
    m.update(current_pw)
    return m.hexdigest()


def dump_user():
    global users
    with open(login_user_file, 'w+') as f:
        f.write(json.dumps(users))


@jwt.expired_token_loader
def expired_token_callback(param):
    return jsonify({
        'status': 0,
        'message': 'The token has expired.',
        'error': 'token_expired'
    })


@jwt.invalid_token_loader
def invalid_token_callback(param):
    return jsonify({
        'status': 0,
        'message': 'token无效'
    })


@web.route('/refresh', methods=['POST'])
@jwt_refresh_token_required
def refresh_token():
    username = get_jwt_identity()
    access_token = create_access_token(identity=username, fresh=False)
    return jsonify(status=200, access_token=access_token)


@web.route("/")
def index():
    """
    自动跳转到登录页
    :return:
    """
    return flask.redirect('home.asp')


@web.route("/home.asp")
def home_page():
    """
    登录页
    :return:
    """
    return render_template('home.html')


@web.route('/login.asp', methods=['GET', 'POST'])
def login():
    global users
    if flask.request.method == 'GET':
        return flask.redirect('/home.asp')
    if os.path.exists(login_user_file):
        with open(login_user_file, 'r') as f:
            file_content = f.read().strip()
            if file_content:
                users = json.loads(file_content)
    username = flask.request.form['username']
    form_pwd = get_hex_pwd(flask.request.form['password'])
    if username in users and form_pwd == users[username]['password']:
        access_token = create_access_token(identity=username)
        rf_token = create_refresh_token(identity=username)
        session["user_id"] = username
        return jsonify(status=200, access_token=access_token, refresh_token=rf_token, sn='')
    return jsonify(status=300, msg="用户名或密码错误")


@web.route("/main.asp", methods=['GET', 'POST'])
def main_page():
    user_id = session.get('user_id')
    if not user_id:
        return flask.redirect('/home.asp')
    sn = ''
    return render_template('main2.html', sn=sn, users=users)


@web.route("/logout", methods=['GET', 'POST'])
@jwt_required
def logout():
    """
    注销登录
    :return:
    """
    if session.get("user_id"):
        del session["user_id"]
    return 'logout'


@web.route('/reset_password', methods=['GET', 'POST'])
@jwt_required
def reset_password():
    """
    添加用户
    """
    global users
    if get_jwt_identity() != 'root':
        return jsonify(status=300, msg='权限不足')
    username = request.form.get('username')
    if not username:
        return jsonify(status=300, msg='用户名错误')
    if username not in users:
        return jsonify(status=300, msg='用户不存在')
    if username in ('root', 'admin'):
        return jsonify(status=300, msg='用户不能重置密码')
    users[username]['password'] = get_hex_pwd(Config.default_password)
    dump_user()
    return jsonify(status=200, msg='密码重置成功')


@web.route('/change_password', methods=['GET', 'POST'])
@jwt_required
def change_password():
    global users
    username = get_jwt_identity()
    old_pw_origin = flask.request.form.get('old_pw')
    new_pw_origin = flask.request.form.get('new_pw')
    old_pw = get_hex_pwd(old_pw_origin)
    new_pw = get_hex_pwd(new_pw_origin)
    if old_pw != users[username]['password']:
        return jsonify(status=300, msg='旧密码错误')
    users[username]['password'] = new_pw
    dump_user()
    return jsonify(status=200, msg='密码修改成功')


@web.route('/del_user', methods=['GET', 'POST'])
@jwt_required
def del_user():
    """
    添加用户
    """
    global users
    if get_jwt_identity() != 'root':
        return jsonify(status=300, msg='权限不足')
    username = request.form.get('username')
    if not username:
        return jsonify(status=300, msg='用户名错误')
    if username not in users:
        return jsonify(status=300, msg='用户不存在')
    if username in ('root', 'admin'):
        return jsonify(status=300, msg='用户不能删除')
    del users[username]
    dump_user()
    return jsonify(status=200, msg='用户删除成功')


@web.route('/add_user', methods=['GET', 'POST'])
@jwt_required
def add_user():
    """
    添加用户
    """
    global users
    if get_jwt_identity() != 'root':
        return jsonify(status=300, msg='权限不足')
    username = request.form.get('username')
    if not username:
        return jsonify(status=300, msg='用户已存错误')
    if username in users:
        return jsonify(status=300, msg='用户已存在，请不要重复添加')
    users[username] = {"password": get_hex_pwd(Config.default_password)}
    dump_user()
    return jsonify(status=200, msg='用户添加成功')


@web.route('/config', methods=['GET', 'POST'])
@jwt_required
def config_mng():
    """
    参数设置
    :return:
    """
    act = request.form.get('act')
    if act == 'get':
        mcc, mnc = lte_controller.get_plmn_id()
        is_running = lte_controller.is_ims_running()
        return jsonify(status=200, data={'mcc': mcc, 'mnc': mnc, 'is_run': is_running})
    if act == 'set':
        mcc = request.form.get('mcc')
        mnc = request.form.get('mnc')
        lte_controller.set_plumn_config(mcc, mnc)
    return jsonify(status=200, msg='设置成功')


@web.route("/operate", methods=['GET', 'POST'])
@jwt_required
def operate_mng():
    act = request.form.get('act')
    ret_msg = {
        '1': '启动成功',
        '2': '关闭成功',
        '3': '重启成功',
    }
    msg = ret_msg.get(act)
    if msg is None:
        return jsonify(status=300, msg='参数错误')
    lte_controller.set_device(act)
    return jsonify(status=200, msg=msg)


@web.route("/whitelist", methods=['GET', 'POST'])
@jwt_required
def whitelist_manage():
    act = request.form.get('act')
    if act == 'add':
        imsi = request.form.get('imsi')
        if not imsi:
            return jsonify(status=300, msg='参数错误')
        voice_phone = request.form.get('phone')
        ki = request.form.get('ki')
        opc = request.form.get('opc')
        if not voice_phone or not ki or not opc:
            return jsonify(status=300, msg='参数错误')
        lte_controller.update_user_cfg_for_white_black(1, [imsi], voice_phone, ki, opc, False)
        return jsonify(status=200, msg='添加成功')
    elif act == 'del':
        imsi = request.form.get('imsi')
        if not imsi:
            return jsonify(status=300, msg='参数错误')
        imsi_list = imsi.split(",")
        lte_controller.update_user_cfg_for_white_black(2, imsi_list, '', False)
        return jsonify(status=200, msg='删除成功')
    elif act == 'list':
        result = lte_controller.get_user_cfg_list()
        return jsonify(status=200, data=result)
    return jsonify(status=300, msg='act参数错误')


@web.route("/get_running_status", methods=['GET', 'POST'])
@jwt_required
def get_running_status():
    """
    pcscf
    scscf
    mgcf
    mgcf_网管
    hss_cx
    smc
    :return:
    """
    output = commands.getoutput('cd /root/ims/bin && /bin/bash ./status_ims.sh')
    result = {
        "pcscf": {
            "status": "关闭",
            "name": "pcscf"
        },
        "scscf": {
            "status": "关闭",
            "name": "scscf"
        },
        "mgcf": {
            "status": "关闭",
            "name": "mgcf"
        },
        "mgcf_sip": {
            "status": "关闭",
            "name": "mgcf网管"
        },
        "hss_cx": {
            "status": "关闭",
            "name": "hss_cx"
        },
        "smc": {
            "status": "关闭",
            "name": "smc"
        },
        "nrf": {
            "status": "关闭",
            "name": "nrf"
        },
    }
    if len(output) > 0:
        for item in result.keys():
            result[item]['status'] = '异常'
        pcscf_count = 0
        scscf_count = 0
        output_line = output.split("\n")
        for line in output_line:
            strip_line = line.strip()
            if strip_line.endswith('/root/ims/bin/pcscf'):
                pcscf_count = pcscf_count + 1
            if strip_line.endswith('/root/ims/bin/scscf'):
                scscf_count = scscf_count + 1
            if strip_line.endswith('/root/ims/bin/mgcf'):
                result['mgcf']['status'] = '正常'
            if strip_line.endswith('/root/ims/bin/mgcf_sip'):
                result['mgcf_sip']['status'] = '正常'
            if strip_line.endswith('/root/ims/bin/hss_cx'):
                result['hss_cx']['status'] = '正常'
            if strip_line.endswith('/root/ims/bin/ims_smc'):
                result['smc']['status'] = '正常'
            if strip_line.find("NRF_APP") > 0:
                result['nrf']['status'] = '正常'
        if pcscf_count == 6:
            result['pcscf']['status'] = '正常'
        if scscf_count == 6:
            result['scscf']['status'] = '正常'
    return jsonify(status=200, data=result)


@web.route('/batch_add_user', methods=['POST'])
def upgrade():
    f = request.files['file']
    content = f.read()
    if len(content) == 0:
        return jsonify(status=200, msg='添加失败，文件无内容')
    line_arr = content.split("\n")
    fail_line = []
    succ = 0
    for idx, line in enumerate(line_arr):
        rows_arr = line.split(' ')
        if len(rows_arr) != 4:
            fail_line.append(str(idx + 1))
            continue
        imsi = rows_arr[0].strip()
        phone = rows_arr[1].strip()
        ki = rows_arr[2].strip()
        opc = rows_arr[3].strip()
        if len(imsi) != 15 or len(ki) != 32 or len(opc) != 32 or len(phone) == 0:
            fail_line.append(str(idx + 1))
            continue
        lte_controller.update_user_cfg_for_white_black(1, [imsi], phone, ki, opc, False)
        succ = succ + 1
    msg = '成功【%d】条，失败【%d】条' % (succ, len(fail_line))
    if len(fail_line) > 0:
        msg += '，失败行数 %s' % ','.join(fail_line)
    return jsonify(status=200, msg=msg)
